  ; one and only of the following two lines should be enabled!
  ; org 0x7c00  ; indicates the program will be loaded to 7c00
  jmp 0x7c0:start  ; physical address = segment address * 16 + offset!!
start:
  mov ax, cs
  mov ds, ax
  mov es, ax

  mov bx, boot_msg
  ; show cs
  mov cx, cs
  call bits16_to_bcd
  ; show start
  mov cx, start
  call bits16_to_bcd
  ; show boot_msg
  mov cx, boot_msg
  call bits16_to_bcd
  ; show end
  mov cx, end
  call bits16_to_bcd

  mov ax, boot_msg-111
  mov bp, ax  ; es:bp is the address of the msg
  mov cx, 212  ; cx is the length
  mov ax, 0x1301  ; ah=13, al=01h
  mov bx, 0x0c  ; page num is 0(bh = 0), bl = 0ch
  mov dl, 0
  int 0x10
  jmp $  ; loop forever

; input: al; output: al
bits4_to_bcd:
  cmp al, 10
  jl add_0
  sub al, 10
  add al, 0x41  ; 'A'
  jmp end_translation
add_0:
  add al, 0x30  ; '0'
end_translation:
  ret

; input: ch; output: ax
bits8_to_bcd:
  ; low 4 bits
  mov al, ch
  and al, 0xf
  call bits4_to_bcd
  mov ah, al
  ; high 4 bits
  mov al, ch
  shr al, 4
  call bits4_to_bcd
  ret

; input: cx, bx; output: ax, bx;
; bx = bx + 4
bits16_to_bcd:
  ; high 8 bits in ch
  call bits8_to_bcd
  mov [bx], ax
  add bx, 2
  ; low 8 bits
  mov ch, cl
  call bits8_to_bcd
  mov [bx], ax
  add bx, 3  ; add one more
  ret

  db "^"
  times 10 db "---------|"
  times 10 db "="
boot_msg:
  ; 0x30='0', 0x41='A', 0x61='a'
  times 10 db "+++++++++|"
  db "$"
end:
  times 510-($-$$) db 0
  dw 0xaa55

; valid combinations of index registers
; [BX+SI]
; [BX+DI]
; [BP+SI]
; [BP+DI]
; [SI]
; [DI]
; [BX]
; [BX+SI]+disp8
; [BX+DI]+disp8
; [BP+SI]+disp8
; [BP+DI]+disp8
; [SI]+disp8
; [DI]+disp8
; [BP]+disp8
; [BX]+disp8
; [BX+SI]+disp16
; [BX+DI]+disp16
; [BP+SI]+disp16
; [BP+DI]+disp16
; [SI]+disp16
; [DI]+disp16
; [BP]+disp16
; [BX]+disp16
  
